/* passport.js 用户登录鉴权模块 by zds 2018-11-15 */
const store = require('./store');
const config = require('../config/config');
const { randomString } = require('./often');

// 默认使用游客登录
const guest = {
	id: 0,
	nickname: '游客',
	avatar: '/images/avatar/guest.webp',
	type: 0,
	state: 5,
}
Session.prototype.guest = guest
///////////////////////////////////////////////////////////////////////////////
// 用户 Session 管理模块
function Session(uid){
	this._uid = uid;
}

// 获取redis保存的用户信息
Session.prototype.load = async function(){
	let bean = await store.getSession(this._uid);
	if (bean){
		for (let key in bean){
			let value = bean[key];
			// 解析 json 对象
			if (value.charAt(0) == '{' && value.charAt(value.length - 1) == '}')
				value = JSON.parse(value);
			this[key] = value;
		}
	}
}
// 设置redis的key 和 value
Session.prototype.set = function(name, value){
	if (value){
		this[name] = value;
		if (typeof value == 'object')
			value = JSON.stringify(value);
		store.setSession(this._uid, name, value);
	}
}

// 更改redis的key 和 value
Session.prototype.up = function(_uid, name, value){
	if (value){
		this[name] = value;
		if (typeof value == 'object')
			value = JSON.stringify(value);
		store.setSession(_uid, name, value);
	}
}
// 删除redis的key
Session.prototype.remove = function(name,_uid){
	if (this[name])
		delete this[name];
	store.removeSession(_uid||this._uid, name);
}

///////////////////////////////////////////////////////////////////////////////

// 通行证模块
function Passport(visitor){
	if (visitor){
		for (let key in visitor)
			this[key] = visitor[key];
	} else {
		// 没有 visitor 信息，用游客登录
		this.id = guest.id;
		this.type = guest.type;
		this.nickname = guest.nickname;
		this.avatar = guest.avatar;
	}
}

// 检查用户是否登录
Passport.prototype.isLogin = function(){ 
	return this.id > guest.type;
}

// 是否是普通用户
Passport.prototype.isNormal = function(TYPE){
	return this.type == TYPE.normal;
}

// 检查是否是管理员
Passport.prototype.isAdmin = function() {
	return this.type == 888
}

// 是否是博主
Passport.prototype.isAdvanced = function(TYPE){
	return this.type == TYPE.blogger;
}

// 是否是博主或管理员
Passport.prototype.isBloggerOrAdmin = function(TYPE){
	return this.type == TYPE.blogger || this.type == TYPE.admin;
}

// 是否是审核员
Passport.prototype.isAuditor = function(TYPE) {
	return this.type == TYPE.auditor;
}

Passport.prototype.hasAdvanced = function() {
	return this.type >= 3;
}
Passport.prototype.isManager = function() {
	return this.type == 2;
}
Passport.prototype.hasManager = function() {
	return this.type >= 2;
}
Passport.prototype.isNormal = function() {
	return this.type == 1;
}

//是否可以登录
Passport.prototype.chekCommont =  function(){
	return this.state !== 2 || this.state !== 3 || this.state !== 4;
}

//是否可以评论 
Passport.prototype.checklogin = function(){
	return this.state !== 3 || this.state !== 4
}



// 检查使用有网站管理权限
Passport.prototype.isOwner = function(userId) {
	return (this.type <= 2 && this.id == userId) || this.type >= 3;
}
// 设置令牌用户信息，保存在 visitor 中
Passport.prototype.set = function(ctx, name, value){
	let visitor = ctx.session['visitor'];
	if (!visitor)
		visitor = {};
	// 修改令牌信息
	if (typeof name == 'object'){
		let user = name;
		for (let key in user){
			this[key] = user[key];
			visitor[key] = user[key]
		}
	} else {
		visitor[name] = value;
		this[name] = value;
	}
	visitor.swtuser = ctx.cookies.get('swtuser');
	// 把令牌信息保存在 session 中
	ctx.session.set('visitor', visitor);
}
// 退出登录
Passport.prototype.logout = function(ctx){
	ctx.passport = new Passport();
	let swtuser = ctx.cookies.get('swtuser');
	if (swtuser)
		ctx.cookies.set('swtuser', '', {maxAge: 0});
}
// 恢复用户登录信息
async function resumeSession(ctx){
	
	let visitor;
	// let sid = ctx.request.method == 'POST' ?
	// 	ctx.request.body.access_token : ctx.request.query.access_token;
	// if (sid){
	// 	// 从 token 中恢复 session，不刷新过期时间
	// 	ctx.session = new Session(sid);
	// 	await ctx.session.load();
	// 	visitor = ctx.session['visitor'];
	// 	if (!visitor)
	// 		throw new Error('Invalid token');
	// } else {
			// 从 cookie 中恢复 session，优先支持 ajax 跨域
		sid = ctx.request.header['token'] || ctx.cookies.get('token');
		if (sid){
			// 验证 swtuser 是否有效
			if (sid.length != 32)
				throw new Error('Invalid token');
			ctx.session = new Session(sid);
			await ctx.session.load();
			visitor = ctx.session['visitor'];
		} else {
			// 游客登录
			// 生产随机数字16位
			sid = randomString(32)
			ctx.session = new Session(sid);
			/*var options = {
				maxAge: cookie_expires_in*1000,		// cookie有效时长，单位：毫秒数，默认 -1，表示会话期间有效，关闭浏览器失效
				expires: new Date('2019-07-26'),	// 过期时间，unix时间戳
				path: '/',	// cookie保存路径, 默认是'/'，set时更改，get时同时修改，不然会保存不上，服务同时也获取不到
				domain: '.designchn.com',		// cookie可用域名，“.”开头支持顶级域名下的所有子域名
				secure: false,		// 默认false，设置成true表示只有https可以访问
				httpOnly: false,	// 设置为true表示客户端不可读取
				overwrite: true, 	// 是否覆盖以前设置的同名的 cookie (默认是 false). 如果是 true, 在同一个请求中设置相同名称的所有 Cookie（不管路径或域）是否在设置此Cookie 时从 Set-Cookie 标头中过滤掉。
			}*/
			ctx.cookies.set('token', sid, {httpOnly: false,maxAge: 1000*60*60*24*7});
			visitor = {
				id: 0,
				name: '游客',
				type: 0,
				avatar: '',
				swtuser: sid
			}
		}
	// }
	// 创建通行证
	ctx.passport = new Passport(visitor);
	// ctx.passport.sid = sid;
}
// 添加访问规则
function addRules(pathGrade, rules, defaultGrade){
	for (var i=0; i<rules.length; i++){
		var item = rules[i];
		var grade = defaultGrade;
		var p = item.indexOf(':');
		if (p != -1){
			grade = Number(item.substring(0, p));
			item = item.substring(p + 1);
		}
		// 拆分匹配项
		p = item.indexOf('|');
		if (p == -1){
			// 如果 item 以 / 结束，则去掉末尾的 /
			if (item.substr(-1) == '/')
				item = item.substring(0, item.length - 1);
			pathGrade[item] = grade;
		} else {
			var first = item.substring(0, p);
			pathGrade[first] = grade;
			var field = item.substring(p + 1);
			if (field){
				var p1 = first.lastIndexOf('/');
				var dir = first.substring(0, p1 + 1);
				var vList = field.split('|');
				for (var j=0; j<vList.length; j++){
					var key = dir + vList[j];
					pathGrade[key] = grade;
				}
			}
		}
	}
}
// 通行证拦截器 {grade, pathGrade, rules, prefix}
Passport.intercept = function(opts) {
	opts = Object.assign({}, opts);
	if (!opts.grade)
		opts.grade = 1;		// 默认页面需要登录
	if (!opts.pathGrade)
		opts.pathGrade = {};
	if (opts.rules)
		addRules(opts.pathGrade, opts.rules, opts.grade);
	return async function serve(ctx, next) {
		try {
			await resumeSession(ctx);
		} catch (err){
			return ctx.body = {code: 1003, message: err.message};
		}
		let path = ctx.request.path;
		// 不限制含有扩展名的路径
		if (!path || path == '/' || path.indexOf('.') != -1)
			return await next();
		// 去掉前缀再进行比较
		if (opts.prefix){
			let length = opts.prefix.length;
			if (path.length < length || path.substring(0, length) != opts.prefix)
				return await next();
			path = path.substring(length);
		}
		let grade = 0;
		let p = path.indexOf('/', 1);
		if (p != -1){
			let cModule = path.substring(0, p);
			p += 1;
			let p1 = path.indexOf('/', p);
			let cPage = (p1 == -1) ? path : path.substring(0, p1);
			// 优先获取页面等级
			grade = opts.pathGrade[cPage];
			if (grade === undefined){
				grade = opts.pathGrade[cModule];
				if (grade === undefined)
					grade = 0;
			}
		} 

		console.log(path, 'grade:' + grade, 'type:' + ctx.passport.type);
		if (!grade || ctx.passport.type >= grade){
			await next();
		}
		 else if (!ctx.passport.isLogin()){
			return ctx.body = {code: 1006, message: '未登录'};
		}
		else {
			return ctx.body = {code: 1002, message: '权限不足'};
		}
	}
}

module.exports = {
	Passport,
	Session
}